package com.fintech.pangu.security.authorize.impl;

import com.fintech.pangu.security.authorize.AuthorizeConfigManager;
import com.fintech.pangu.security.authorize.AuthorizeConfigProvider;
import lombok.Setter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;

import java.util.List;

@Setter  // 也可以通过set方法设置AuthorizeConfigProvider集合
public class DefaultAuthorizeConfigManager implements AuthorizeConfigManager {

    /**
     * AuthorizeConfigProvider权限配置提供者集合
     */
    private List<AuthorizeConfigProvider> authorizeConfigProviders;


    public DefaultAuthorizeConfigManager() {
    }

    /**
     * 权限配置信息管理器内部会找到Spring容器内所有AuthorizeConfigProvider
     * 并逐个遍历添加对应的权限配置
     * @param config
     */
    @Override
    public void config(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry config) {
        boolean existAnyRequestConfig = false;  // 是否存在AnyRequest配置
        String existAnyRequestConfigName = null; // 发生重复的AnyRequest配置类名

        if(authorizeConfigProviders!=null && authorizeConfigProviders.size()>0){
            for (AuthorizeConfigProvider authorizeConfigProvider : authorizeConfigProviders) {
                boolean currentIsAnyRequestConfig = authorizeConfigProvider.config(config);

                // 如果 已经存在AnyRequest配置 且 当前授权配置类也存在AnyRequest配置，抛异常
                if (existAnyRequestConfig && currentIsAnyRequestConfig) {
                    throw new RuntimeException("重复的anyRequest配置:" + existAnyRequestConfigName + ","
                            + authorizeConfigProvider.getClass().getSimpleName());
                }
                // 如果 当前权限配置类存在AnyRequest配置，记录
                else if (currentIsAnyRequestConfig) {
                    existAnyRequestConfig = true;
                    existAnyRequestConfigName = authorizeConfigProvider.getClass().getSimpleName();
                }
            }
        }

        // 如果所有AuthorizeConfigProvider都没有anyRequest配置，使用authenticated()
        if(!existAnyRequestConfig){
            config.anyRequest().authenticated();
        }
    }

}
